package com.xiaotao.task;

import com.xiaotao.entity.TeamPost;
import com.xiaotao.mapper.TeamMemberMapper;
import com.xiaotao.mapper.TeamPostMapper;
import com.xiaotao.mapper.UserLikeMapper;
import com.xiaotao.service.TeamPostService;
import com.xiaotao.util.RecommendUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
public class PostTask {

    @Autowired
    private TeamPostMapper teamPostMapper;

    @Autowired
    private TeamPostService teamPostService;

    @Autowired
    private RecommendUtil recommendUtil;

    @Autowired
    private UserLikeMapper userLikeMapper;

    @Autowired
    private TeamMemberMapper teamMemberMapper;

    /**
     * 每30分钟更新一次推荐分数
     */
    @Scheduled(fixedRate = 1800000) // 30分钟
    @Async
    public void scheduledUpdateRecommendations() {
        updatePostRecommendations();
    }

    /**
     * 每天凌晨2点关闭过期帖子
     */
    @Scheduled(cron = "0 0 2 * * ?")
    @Async
    public void scheduledCloseExpiredPosts() {
        closeExpiredPosts();
    }

    /**
     * 每周日凌晨3点清理无效数据
     */
    @Scheduled(cron = "0 0 3 ? * SUN")
    @Async
    public void scheduledCleanupInvalidData() {
        cleanupInvalidData();
    }

    /**
     * 更新帖子推荐分数
     */
    @Async
    public void updatePostRecommendations() {
        try {
            log.info("开始更新帖子推荐分数...");
            teamPostService.calculateRecommendScores();
            log.info("帖子推荐分数更新完成");
        } catch (Exception e) {
            log.error("更新帖子推荐分数失败", e);
        }
    }

    /**
     * 关闭过期帖子
     */
    @Async
    public void closeExpiredPosts() {
        try {
            log.info("开始关闭过期帖子...");
            List<TeamPost> activePosts = teamPostMapper.selectAllActivePosts();
            LocalDateTime now = LocalDateTime.now();

            int closedCount = 0;
            for (TeamPost post : activePosts) {
                if (post.getEndTime() != null &&
                        post.getEndTime().isBefore(now) &&
                        !"已结束".equals(post.getStatus())) {

                    post.setStatus("已结束");
                    teamPostMapper.update(post);
                    closedCount++;
                }
            }
            log.info("成功关闭 {} 个过期帖子", closedCount);
        } catch (Exception e) {
            log.error("关闭过期帖子失败", e);
        }
    }

    /**
     * 清理无效数据
     */
    @Async
    public void cleanupInvalidData() {
        try {
            log.info("开始清理无效数据...");
            List<TeamPost> allPosts = teamPostMapper.selectAllActivePosts();
            List<TeamPost> deletedPosts = allPosts.stream()
                    .filter(post -> post.getIsDeleted() == 1)
                    .collect(Collectors.toList());

            for (TeamPost post : deletedPosts) {
                userLikeMapper.deleteByPostId(post.getId());
                teamMemberMapper.deleteByPostId(post.getId());
            }
            log.info("无效数据清理完成，清理了 {} 个帖子相关数据", deletedPosts.size());
        } catch (Exception e) {
            log.error("清理无效数据失败", e);
        }
    }

    /**
     * 更新热门帖子分数
     */
    @Async
    public void updateHotPosts() {
        try {
            log.info("开始更新热门帖子分数...");

            List<TeamPost> allPosts = teamPostMapper.selectAllActivePosts();
            for (TeamPost post : allPosts) {
                // 计算热度分数（点赞*10 + 浏览*1 + 申请*5）
                int hotScore = post.getLikeCount() * 10 +
                        post.getViewCount() * 1 +
                        post.getApplyCount() * 5;

                // 更新帖子推荐分数
                post.setRecommendScore(hotScore);
                teamPostMapper.updateRecommendScore(post);
            }

            log.info("热门帖子分数更新完成，共处理 {} 个帖子", allPosts.size());
        } catch (Exception e) {
            log.error("更新热门帖子分数失败", e);
        }
    }
}